package com.derbysoft.dswitch.adapter.ihg.web.action.admin.setting.channel;

import com.derbysoft.dswitch.adapter.ihg.common.domain.ChannelAuthorization;
import com.derbysoft.dswitch.adapter.ihg.common.domain.RatePlan;
import com.derbysoft.dswitch.adapter.ihg.common.repository.ChannelAuthorizationRepository;
import com.derbysoft.dswitch.adapter.ihg.common.repository.RatePlanRepository;
import com.derbysoft.dswitch.adapter.ihg.exception.ChannelExistedException;
import com.derbysoft.dswitch.adapter.ihg.exception.ChannelNotFoundException;
import com.derbysoft.dswitch.adapter.ihg.web.action.DMXAbstractAction;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/**
 * User: jason
 * Date: 2013-02-04
 */
public class DMXAction extends DMXAbstractAction {
    @Autowired
    private ChannelAuthorizationRepository channelAuthorizationRepository;

    @Autowired
    private RatePlanRepository ratePlanRepository;

    private String channelCode;

    private ChannelAuthorization channel;

    private String channelCodes;

    @Action("dmxQueryChannels")
    public String dmxQueryAll() {
        try {
            getPaginater().getObjects().addAll(createChannelMappings());
            return populateSucceededJsonResult(dmxPaging());
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    private List<ChannelRatePlanMapping> createChannelMappings() {
        List<ChannelRatePlanMapping> channelRatePlanMappings = new ArrayList<ChannelRatePlanMapping>();
        for (ChannelAuthorization channelAuthorization : channelAuthorizationRepository.loadAll()) {
            List<String> ratePlanCodes = getRatePlanCodes(channelAuthorization.getRatePlans());
            channelRatePlanMappings.add(new ChannelRatePlanMapping(channelAuthorization, ratePlanCodes));
        }
        return channelRatePlanMappings;
    }

    @Action("dmxLoadAllChannels")
    public String dmxLoadAllChannels(){
        try {
            return populateSucceededJsonResult(getRatePlanCodes(ratePlanRepository.loadAll()));
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxQueryChannel")
    public String dmxQueryChannel() {
        try {
            if (StringUtils.isBlank(channelCode)) {
                return populateSucceededJsonResult("");
            }
            ChannelAuthorization channelAuthorization = channelAuthorizationRepository.loadByDerbyChannelCode(channelCode);
            if (channelAuthorization == null) {
                return populateSucceededJsonResult("");
            }
            return populateSucceededJsonResult(new ChannelRatePlanMapping(channelAuthorization, getRatePlanCodes(ratePlanRepository.loadAll())));
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    private List<String> getRatePlanCodes(List<RatePlan> ratePlans) {
        List<String> ratePlanCodes = new ArrayList<String>();
        for (RatePlan ratePlan : ratePlans) {
            ratePlanCodes.add(ratePlan.getCode());
        }
        return ratePlanCodes;
    }

    @Action("dmxUpdateChannel")
    public String dmxUpdateChannel() {
        try {
            if (emptyCondition()) {
                return populateSucceededJsonResult("");
            }
            ChannelAuthorization authorization = channelAuthorizationRepository.loadByDerbyChannelCode(channel.getDerbyChannelCode());
            if (authorization == null) {
                throw new ChannelNotFoundException(String.format("[%s] : ChannelAuthorization not found !!", channel.getDerbyChannelCode()));
            }
            setChannelProperties(authorization);
            if (StringUtils.isBlank(channelCodes)) {
                authorization.getRatePlans().clear();
            } else {
                authorization.setRatePlans(createChannels());
            }
            channelAuthorizationRepository.save(authorization);
            return populateSucceededJsonResult(authorization);
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    private List<RatePlan> createChannels() {
        List<RatePlan> ratePlans = new ArrayList<RatePlan>();
        String[] ratePlanCodeList = StringUtils.split(channelCodes, ",");
        for (String ratePlan : ratePlanCodeList) {
            RatePlan exist = ratePlanRepository.loadByCode(ratePlan.trim());
            if (exist != null) {
                ratePlans.add(exist);
            }
        }
        return ratePlans;
    }

    private void setChannelProperties(ChannelAuthorization authorization) {
        authorization.setIataNumber(channel.getIataNumber());
        authorization.setUserName(channel.getUserName());
        authorization.setPassword(channel.getPassword());
    }

    private boolean emptyCondition() {
        return channel == null
                || StringUtils.isBlank(channel.getDerbyChannelCode())
                || StringUtils.isBlank(channel.getUserName())
                || StringUtils.isBlank(channel.getPassword())
                || StringUtils.isBlank(channel.getIataNumber());
    }

    @Action("dmxSaveChannel")
    public String dmxSaveChannel() {
        try {
            if (emptyCondition()) {
                return populateSucceededJsonResult("");
            }
            ChannelAuthorization authorization = channelAuthorizationRepository.loadByDerbyChannelCode(StringUtils.upperCase(channel.getDerbyChannelCode()));
            if (authorization != null) {
                throw new ChannelExistedException(String.format("[%s] : Channel existed !!", channel.getDerbyChannelCode()));
            }
            if (StringUtils.isBlank(channelCodes)) {
                channel.getRatePlans().clear();
            } else {
                channel.setRatePlans(createChannels());
            }
            channel.setDerbyChannelCode(StringUtils.upperCase(channel.getDerbyChannelCode()));
            channelAuthorizationRepository.save(channel);
            return populateSucceededJsonResult(channel);
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    @Action("dmxDeleteChannel")
    public String dmxDeleteChannel() {
        try {
            if (StringUtils.isBlank(channelCode)) {
                return populateSucceededJsonResult("");
            }
            ChannelAuthorization channelAuthorization = channelAuthorizationRepository.loadByDerbyChannelCode(StringUtils.upperCase(StringUtils.trim(channelCode)));
            if (channelAuthorization == null) {
                return populateSucceededJsonResult("");
            }
            channelAuthorizationRepository.delete(channelAuthorization);
            return populateSucceededJsonResult(channelAuthorization);
        } catch (Exception ex) {
            return populateFailedJsonResult(ex);
        }
    }

    public String getChannelCode() {
        return channelCode;
    }

    public void setChannelCode(String channelCode) {
        this.channelCode = channelCode;
    }

    public ChannelAuthorization getChannel() {
        return channel;
    }

    public void setChannel(ChannelAuthorization channel) {
        this.channel = channel;
    }

    public String getChannelCodes() {
        return channelCodes;
    }

    public void setChannelCodes(String channelCodes) {
        this.channelCodes = channelCodes;
    }
}
